package com.ds.infrastructure.hyperspace.console.service.impl;

import com.ds.infrastructure.hyperspace.console.common.methodlock.MethodLock;
import com.ds.infrastructure.hyperspace.console.common.methodlock.MethodLockId;
import com.ds.infrastructure.hyperspace.console.constants.ConsoleConstant;
import com.ds.infrastructure.hyperspace.console.constants.MethodLockConstant;
import com.ds.infrastructure.hyperspace.console.dao.dao.TbDeployConfigDao;
import com.ds.infrastructure.hyperspace.console.dto.deploydata.DeployDataDTO;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbDeployConfigEnum;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbPublicEnum;
import com.ds.infrastructure.hyperspace.console.entity.page.TbPageWhere;
import com.ds.infrastructure.hyperspace.console.entity.table.TbDeployConfig;
import com.ds.infrastructure.hyperspace.console.entity.where.TbCustomWhere;
import com.ds.infrastructure.hyperspace.console.entity.where.TbDeployConfigCustomWhere;
import com.ds.infrastructure.hyperspace.console.service.inf.IDeployConfigService;
import com.ds.infrastructure.hyperspace.console.utils.FastJsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author: yaozhendong
 * @create: 2019-10-21 11:45
 **/

@Service
public class DeployConfigService implements IDeployConfigService {
    @Autowired
    TbDeployConfigDao tbDeployConfigDao;

    @Override
    public int save(TbDeployConfig record) {
        return tbDeployConfigDao.insertSelective(record);
    }

    @Override
    public int update(TbDeployConfig record) {
        return tbDeployConfigDao.updateByPrimaryKeySelective(record);
    }

    @Override
    public TbDeployConfig get(Long id) {
        TbDeployConfig entity = tbDeployConfigDao.selectByPrimaryKey(id);
        if (entity != null && TbPublicEnum.GMD_IS_DEL.NO.code.equals(entity.getGmtIsDeleted())) {
            return entity;
        }
        return null;
    }

    @Override
    public int delete(Long id) {
        TbDeployConfig item = new TbDeployConfig();
        item.setId(id);
        item.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.YES.code);
        return update(item);
    }

    @Override
    public List<TbDeployConfig> getList(TbDeployConfig where, TbCustomWhere customWhere, TbPageWhere pageWhere) {
        return tbDeployConfigDao.selectListForPage(where, customWhere, pageWhere);
    }

    @Override
    public int getTotal(TbDeployConfig where, TbCustomWhere customWhere) {
        return tbDeployConfigDao.selectListForPageCount(where, customWhere);
    }

    @Override
    public TbDeployConfig selectOne(TbDeployConfig where, TbCustomWhere customWhere) {
        List<TbDeployConfig> itemList = tbDeployConfigDao.selectListForPage(where, customWhere, TbPageWhere.newPage4OnlyOne());
        return itemList.stream().findFirst().orElseGet(() -> null);
    }

    @Override
    public Integer selectMaxForConfigVersion(TbDeployConfig where, TbCustomWhere mapWhere) {
        return tbDeployConfigDao.selectMaxForConfigVersion(where, mapWhere);
    }

    @Override
    public void active(MethodLockId methodLockId, TbDeployConfig entity) {
        copy(entity);
        updateEditState(entity);
    }

    private void updateEditState(TbDeployConfig entity) {
        TbDeployConfig newEntity = new TbDeployConfig();
        newEntity.setId(entity.getId());
        newEntity.setGmtModified(entity.getGmtModified());
        newEntity.setEditState(TbDeployConfigEnum.EDIT_STATE.NO.code);
        updateWithTimestamp(newEntity);
    }

    private void copy(TbDeployConfig entity) {
        TbDeployConfig newEntity = new TbDeployConfig();
        newEntity.setStageId(entity.getStageId());
        newEntity.setEnvironmentId(entity.getEnvironmentId());
        newEntity.setConfigDataVersion(entity.getConfigDataVersion());
        newEntity.setEditState(TbDeployConfigEnum.EDIT_STATE.YES.code);
        newEntity.setDescription(entity.getDescription());
        newEntity.setConfigData(entity.getConfigData());
        newEntity.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.NO.code);
        saveWithConfigVersion(newEntity);
    }

    @Override
    public TbDeployConfig selectLastOne(Long stageId, Long environmentId) {
        TbDeployConfig where = new TbDeployConfig();
        where.setStageId(stageId);
        where.setEnvironmentId(environmentId);
        where.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.NO.code);
        TbCustomWhere customWhere = new TbDeployConfigCustomWhere().setOrderByType(TbPublicEnum.ORDER_BY_TYPE.ID_DESC.value);
        TbDeployConfig entity = selectOne(where, customWhere);
        if (entity == null) {
            return null;
        }
        return get(entity.getId());

    }

    @Override
    @MethodLock(name = MethodLockConstant.DEPLOY_CONFIG_SERVICE_FOR_GET_LAST_ONE_METHOD)
    public TbDeployConfig getLastOneWithMethodLockId(MethodLockId methodLockId, Long stageId, Long environmentId) {
        TbDeployConfig entity = selectLastOne(stageId, environmentId);
        if (entity != null) {
            return entity;
        }
        TbDeployConfig newEntity = createDefaultEntity(environmentId, stageId);
        saveWithConfigVersion(newEntity);
        //获取最新时间戳
        return get(newEntity.getId());
    }

    @Override
    public int updateWithTimestamp(TbDeployConfig entity) {
        return tbDeployConfigDao.updateWithTimestamp(entity);
    }

    @Override
    public void updateVersion(TbDeployConfig entity) {
        updateEditState(entity);
        copy(entity);
    }

    @Override
    public TbDeployConfig selectLastOneForInstalled(Long stageId, Long environmentId) {
        TbDeployConfig where = new TbDeployConfig();
        where.setStageId(stageId);
        where.setEnvironmentId(environmentId);
        where.setEditState(TbDeployConfigEnum.EDIT_STATE.NO.code);
        where.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.NO.code);
        TbCustomWhere customWhere = new TbDeployConfigCustomWhere().setOrderByType(TbPublicEnum.ORDER_BY_TYPE.ID_DESC.value);
        return selectOne(where, customWhere);
    }

    private void saveWithConfigVersion(TbDeployConfig entity) {
        int maxConfigVersion = selectMaxForConfigVersionByStageId(entity.getStageId());
        entity.setConfigVersion(++maxConfigVersion);
        save(entity);
    }

    private TbDeployConfig createDefaultEntity(Long environmentId, Long stageId) {
        TbDeployConfig tbDeployConfig = new TbDeployConfig();
        tbDeployConfig.setStageId(stageId);
        tbDeployConfig.setEnvironmentId(environmentId);
        tbDeployConfig.setConfigData(FastJsonUtil.serialize(new DeployDataDTO()));
        tbDeployConfig.setConfigDataVersion(ConsoleConstant.CONTAINER_CONFIG_DATA_VERSION);
        tbDeployConfig.setEditState(TbDeployConfigEnum.EDIT_STATE.YES.code);
        tbDeployConfig.setGmtModified(new Date());
        tbDeployConfig.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.NO.code);
        return tbDeployConfig;
    }

    public int selectMaxForConfigVersionByStageId(Long stageId) {
        TbDeployConfig where = new TbDeployConfig();
        where.setStageId(stageId);
        where.setGmtIsDeleted(TbPublicEnum.GMD_IS_DEL.NO.code);
        Integer maxId = selectMaxForConfigVersion(where, null);
        return maxId == null ? 0 : maxId;
    }
}
